package com.dy.回溯算法.单词搜索;

/*
给定一个二维网格和一个单词，找出该单词是否存在于网格中。

单词必须按照字母顺序，通过相邻的单元格内的字母构成，其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。

示例:

board =
[
  ['A','B','C','E'],
  ['S','F','C','S'],
  ['A','D','E','E']
]

给定 word = "ABCCED", 返回 true.
给定 word = "SEE", 返回 true.
给定 word = "ABCB", 返回 false.
 */
public class Solution {
    public boolean exist(char[][] board, String word) {

        if (board == null || board.length == 0 || board.length * board[0].length < word.length()) return false;

        boolean mark[][] = new boolean[board.length][board[0].length];
        for (int i = 0; i < board.length; i++) {
            for (int j = 0; j < board[0].length; j++) {
                if (board[i][j] == word.charAt(0)) {
                    if (dfs(board, mark, word, 0, i, j) == true) {
                        return true;
                    }
                }
            }
        }
        return false;
    }

    private boolean dfs(char[][] board, boolean mark[][], String word, int n, int x, int y) {
        if (n == word.length()) {
            return true;
        }
        if (x < 0 || x >= board.length || y < 0 || y >= board[0].length //超过边界
                || board[x][y] != word.charAt(n) //不相等
                || mark[x][y]) //已经走过
        {
            return false;
        }
        mark[x][y] = true;
        if (dfs(board, mark, word, n + 1, x + 1, y) ||
                dfs(board, mark, word, n + 1, x - 1, y) ||
                dfs(board, mark, word, n + 1, x, y + 1) ||
                dfs(board, mark, word, n + 1, x, y - 1)
        ) {
            return true;
        }
        mark[x][y] = false;
        return false;
    }
}
